package com.jh.paymentchannel.service;

import cn.jh.common.utils.CommonConstants;
import com.jh.paymentchannel.business.TopupPayChannelBusiness;
import com.jh.paymentchannel.util.PaymentChannelConstants;
import com.jh.paymentchannel.util.SignUtils;
import com.jh.paymentchannel.util.Util;
import net.sf.json.JSONObject;
import org.apache.http.HttpResponse;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.net.URI;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 惠至快捷统一支付接口 20180601
 * 
 * @author FJW
 *
 */
@Service
public class HuiZhiQuickTopupRequest implements RepaymentRequest {

	private static final Logger log = LoggerFactory.getLogger(HuiZhiQuickTopupRequest.class);

	/**
	 * 惠至商户号&key&接口地址
	 */
	//@Value("${huizhi.merId}")
	private  String merId;

	//@Value("${huizhi.merKey}")
	private  String merKey;

	//@Value("${huizhi.transUrl}")
	private  String transUrl;
	
	//@Value("${payment.ipAddress}")
	private String ipAddress;

	@Autowired
	private TopupPayChannelBusiness topupPayChannelBusiness;

	@Autowired
	private Util util;

	@Override
	public Map<String, String> topupRequest(HttpServletRequest request, String amount, String ordercode,
			String orderdesc, String extra, String notifyurl, String returnurl, String channelParam) throws Exception {
		log.info("进入惠至快捷支付通道入口……");
		Map<String, String> map = new HashMap<String, String>();
		map.put("channel_type", PaymentChannelConstants.CHANNEL_HUIZHI_QUICK.toLowerCase());

		/******* 订单信息查询 *******/
		RestTemplate restTemplate = new RestTemplate();
		URI uri = util.getServiceUrl("transactionclear", "error url request!");
		String url = uri.toString() + "/v1.0/transactionclear/payment/query/ordercode";
		MultiValueMap<String, String> requestEntity = new LinkedMultiValueMap<String, String>();
		requestEntity.add("order_code", ordercode);
		String result = restTemplate.postForObject(url, requestEntity, String.class);
		log.info("查询订单信息结果result={}" + result);
		JSONObject jsonObject;
		JSONObject orderResultObj;
		try {
			jsonObject = JSONObject.fromObject(result);
			orderResultObj = jsonObject.getJSONObject("result");
		} catch (Exception e) {
			log.error("查询订单信息出错");
			map.put("channel_type", PaymentChannelConstants.CHANNEL_HUIZHI_QUICK);
			map.put(CommonConstants.RESP_CODE, CommonConstants.FALIED);
			map.put(CommonConstants.RESP_MESSAGE, "没有该订单信息");
			return map;
		}
		String userid = orderResultObj.getString("userid");
		// 费率
		String rate = orderResultObj.getString("rate");
		// 额外费用
		String extraFee = orderResultObj.getString("extraFee");
		// 信用卡账号
		String bankCard = orderResultObj.getString("bankcard");
		/** 0 充值 1支付 2提现 3退款 7信用卡还款 8信用卡还款账户充值 */
		String orderType = orderResultObj.getString("type");
		// 实际到账金额
		String realAmount = orderResultObj.getString("realAmount");
		// 渠道标识
		String orderChannleTag = orderResultObj.getString("channelTag");
		// 品牌id
		String brandId = orderResultObj.getString("brandid");

		/******* 查询结算卡（储蓄卡）信息 *******/
		restTemplate = new RestTemplate();
		uri = util.getServiceUrl("user", "error url request!");
		url = uri.toString() + "/v1.0/user/bank/default/userid";
		requestEntity = new LinkedMultiValueMap<String, String>();
		requestEntity.add("user_id", userid);
		result = restTemplate.postForObject(url, requestEntity, String.class);
		String respCode = "";
		log.info("查询默认结算卡/v1.0/user/bank/default/userid ==RESULT=========" + result);
		JSONObject defaultCardResultObj;
		try {
			jsonObject = JSONObject.fromObject(result);
			defaultCardResultObj = jsonObject.getJSONObject("result");
			respCode = jsonObject.getString("resp_code");
		} catch (Exception e) {
			log.error("查询结算卡异常" + e.getMessage());
			map.put(CommonConstants.RESP_CODE, CommonConstants.FALIED);
			map.put(CommonConstants.RESP_MESSAGE, "无默认结算卡,请绑定默认结算卡");
			return map;
		}

		if (!CommonConstants.SUCCESS.equals(respCode)) {
			map.put(CommonConstants.RESP_CODE, CommonConstants.FALIED);
			map.put(CommonConstants.RESP_MESSAGE, "没有结算卡");
			return map;
		}

		// 结算卡卡号
		String cardNo = defaultCardResultObj.getString("cardNo");
		// 预留银行卡手机号码
		String mobile = defaultCardResultObj.getString("phone");
		// 身份证号
		String idcard = defaultCardResultObj.getString("idcard");
		// 用户姓名
		String userName = defaultCardResultObj.getString("userName");
		// 银行名称
		String bankName = defaultCardResultObj.getString("bankName");

		log.info(bankName+"银行名字====================================" );
		// 转换为惠至快捷支付对应的银行码
		String hzBankCode = topupPayChannelBusiness.getHZQuickBankCodeByBankName(bankName);

		// 用户姓名
		String province = defaultCardResultObj.getString("province");
		// 银行名称
		String city = defaultCardResultObj.getString("city");

		/******* 查询银行卡（信用卡）信息 *******/
		restTemplate = new RestTemplate();
		uri = util.getServiceUrl("user", "error url request!");
		url = uri.toString() + "/v1.0/user/bank/default/cardno";
		requestEntity = new LinkedMultiValueMap<String, String>();
		requestEntity.add("cardno", bankCard);
		requestEntity.add("type", "0");
		result = restTemplate.postForObject(url, requestEntity, String.class);
		log.info("接口/v1.0/user/bank/default/cardno--RESULT================" + result);
		JSONObject cardResultObj;
		try {
			jsonObject = JSONObject.fromObject(result);
			cardResultObj = jsonObject.getJSONObject("result");
		} catch (Exception e) {
			map.put(CommonConstants.RESP_CODE, CommonConstants.FALIED);
			map.put(CommonConstants.RESP_MESSAGE, "查询银行卡信息有误");
			return map;
		}
		// 信用卡银行名称
		String creditCardBankName = cardResultObj.getString("bankName");
		// 转换为惠至快捷支付对应的银行码
		String hzCreditCardBankCode = topupPayChannelBusiness.getHZQuickBankCodeByBankName(creditCardBankName);
		// 预留银行卡手机号码
		String creditCardMobile = defaultCardResultObj.getString("phone");
		// 到期时间
		String expiredTime = cardResultObj.getString("expiredTime");
		// 安全码
		String securityCode = cardResultObj.getString("securityCode");

		/******* 封装请求参数 ******/
		DefaultHttpClient httpClient = new DefaultHttpClient();
		HttpPost postMethod = new HttpPost(transUrl);
		List<BasicNameValuePair> nvps = new ArrayList<BasicNameValuePair>();
		nvps.add(new BasicNameValuePair("merchantId", merId));
		// 订单号，惠至订单号不超过32位
		Random random = new Random();
		//String orderCode = "HS" + DateUtil.getDateStringConvert(new String(), new Date(),"yyyyMMddHHSSS")+random.nextInt(9)+random.nextInt(9)+random.nextInt(9)+random.nextInt(9)+"1";
		nvps.add(new BasicNameValuePair("merOrderId",ordercode));
		nvps.add(new BasicNameValuePair("totalFee",
				new BigDecimal(amount).multiply(new BigDecimal("100")).setScale(0).toString()));// 总金额，单位为分
		nvps.add(new BasicNameValuePair("body", "酒店入住"));// 商品名称 随便设置的固定值
		nvps.add(new BasicNameValuePair("accType", "CREDIT"));// 固定CREDIT信用卡
		nvps.add(new BasicNameValuePair("accName", userName));// 用户名
		nvps.add(new BasicNameValuePair("accNo", bankCard));// 信用卡账号
		nvps.add(new BasicNameValuePair("bankCode", hzCreditCardBankCode));// 信用卡银行代码
		nvps.add(new BasicNameValuePair("idType", "01"));// 固定01身份证
		nvps.add(new BasicNameValuePair("idNo", idcard));// 身份证
		nvps.add(new BasicNameValuePair("cvn2", securityCode));// 安全码
		nvps.add(new BasicNameValuePair("expire", expiredTime));// 有效期
		nvps.add(new BasicNameValuePair("mobile", creditCardMobile));// 手机号
		//取回跳地址
		nvps.add(new BasicNameValuePair("frontNotifyUrl", returnurl));// 前端回跳地址
		nvps.add(new BasicNameValuePair("backNotifyUrl", notifyurl));// 后台通知回调地址
		nvps.add(new BasicNameValuePair("settRate", rate));// 费率
		nvps.add(new BasicNameValuePair("settAffix",
				new BigDecimal(extraFee).multiply(new BigDecimal("100")).setScale(0).toString()));// 固收手续费，单位分
		nvps.add(new BasicNameValuePair("settBankCode", hzBankCode));// 储蓄卡银行代码
		nvps.add(new BasicNameValuePair("settAccNo", cardNo));// 储蓄卡账号
		nvps.add(new BasicNameValuePair("settAccProvince", province));// 省份
		nvps.add(new BasicNameValuePair("settAccCity", city));// 城市
		nvps.add(new BasicNameValuePair("settMobile", mobile));// 手机号
		nvps.add(new BasicNameValuePair("address", "上海市浦东新区张港路233号"));// 随便设置的固定值
		nvps.add(new BasicNameValuePair("transChannel", "sl0"));// 固定s10商旅
		nvps.add(new BasicNameValuePair("timeStamp", new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())));
		String md5Data = SignUtils.signMD5Datas(nvps, merKey);
		log.info("md5签名后的字符串：" + md5Data);
		nvps.add(new BasicNameValuePair("sign", md5Data));
		try {
			postMethod.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));
			HttpResponse resp = httpClient.execute(postMethod);
			String retrunStr = EntityUtils.toString(resp.getEntity(), "UTF-8");
			log.info("返回结果：" + retrunStr);
			int statusCode = resp.getStatusLine().getStatusCode();
			if (200 == statusCode) {
				log.info("=======================200");
				JSONObject resJson = JSONObject.fromObject(retrunStr);
				String resCode = resJson.getString("resCode");
				String resMsg = resJson.getString("resMsg");
				// 支付请求下单成功,返回数据，当前是无法获得支付结果的
				if ("0000".equals(resCode)) {
					map.put(CommonConstants.RESP_CODE, "success");
					map.put(CommonConstants.RESP_MESSAGE, "成功");
					String data = resJson.getString("data");
					map.put("redirect_url", queryUrl(data));// 数据包含跳转惠至h5页面，进行支付确认操作
					return map;
				} else {
					map.put(CommonConstants.RESP_CODE, CommonConstants.FALIED);
					map.put(CommonConstants.RESP_MESSAGE, "支付失败");
					return map;
				}
			} else {
				map.put(CommonConstants.RESP_CODE, CommonConstants.FALIED);
				map.put(CommonConstants.RESP_MESSAGE, "通信异常");
				return map;
			}
		} catch (Exception e) {
			log.error("error",e);
			map.put(CommonConstants.RESP_CODE, CommonConstants.FALIED);
			map.put(CommonConstants.RESP_MESSAGE, "系统异常");
			return map;
		}
	}

	private  static  String queryUrl(String data) {

		String s = data;
		String mode = "(http[s]?:\\/\\/([\\w-]+\\.)+[\\w-]+([\\w-./?%&*=]*))";
		Pattern p = Pattern.compile(mode);
		Matcher m = p.matcher(s);
		String s1 = "";
		String url=null;
		int i = 0;
		while (m.find()) {
			 url = m.group();
			if (i > 0) {
				s1 = s1.replaceAll(url, "<a href=\'" + url + "\'" + " target=\'_blank\'>" + url + "</a>");
				System.out.println(i);
			} else {
				s1 = s.replaceAll(url, "<a href=\'" + url + "\'" + " target=\'_blank\'>" + url + "</a>");
			}
			i++;
			log.info("url===============" + url);
		}
	return  url;
	}
	@Override
	public Map<String, String> verifyBindCardRequest(HttpServletRequest request, String channelTag, String userId,
			String creditCardNumber, String brandId) throws Exception {
		// TODO Auto-generated method stub
		return null;
	}


}